package com.lijie.ljblog.socketAPI;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lijie.ljblog.chess.GameMatch;
import com.lijie.ljblog.chess.OnlineUserManager;
import com.lijie.ljblog.model.vo.MatchRequestVO;
import com.lijie.ljblog.model.vo.MatchResponseVO;
import com.lijie.ljblog.util.GoBangBotUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @Description
 * @Author lijie
 * @Date 2022/8/26 16:25
 **/
@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler{
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    OnlineUserManager onlineUserManager;
    @Autowired
    GameMatch gameMatch;

    /**
     *  用户进入大厅
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //session.getAttributes()获取到的是一个map，里面存放了了HttpSession中的getAttribute里的所有对象
        Integer userId = GoBangBotUtil.getUserId(session);
        MatchResponseVO response = new MatchResponseVO();
        if (userId==null){
            return;
        }
        if(userId<0){
            //玩家还未登陆就进入游戏大厅了
            response.error("[afterConnectionEstablished]玩家尚未登录!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        //检查玩家的上线状态（是否多开）
        //在给玩家设置上线状态时，需要先判断之前玩家是否已经登录过了
        if (onlineUserManager.getGameHallSession(userId) != null
                || onlineUserManager.getGameRoomSession(userId) != null){
            response.error("当前游戏禁止多开");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        //当玩家获取到身份信息后，就可以给玩家设置上线状态了
        onlineUserManager.enterGameHall(userId,session);
        log.info("当前玩家" + userId + "进入游戏大厅");
    }

    /**
     * 开始 /  取消匹配
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);
        if(userId == null){
            log.info("[handleTextMessage]玩家尚未登录");
            return;
        }
        log.info("开始匹配" + userId + "message" + message.toString());
        //将解析得到的JSON请求数据转换为一个MatchRequest对象
        MatchRequestVO request = objectMapper.readValue(message.getPayload(),MatchRequestVO.class);
        MatchResponseVO response = new MatchResponseVO();
        try {
            if("startMatch".equals(request.getMessage())){
                //加入匹配器中
                if(gameMatch.checkUserOnQueue(userId)){
                    response.error("已经在匹配队列中啦~");
                }else {
                    gameMatch.add(userId);
                }
            }else if("stopMatch".equals(request.getMessage())){
                //从匹配器中移除
                gameMatch.remove(userId);
                response.setReason("stopMatch");
            }else{
                response.error("非法的匹配请求");
            }
        }catch (Exception e){
            response.error(e.getMessage());
        }

        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);
        if (!ObjectUtils.isEmpty(userId)) {

            WebSocketSession tmpSession = onlineUserManager.getGameHallSession(userId);
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(userId);
            }
            gameMatch.remove(userId);
            log.info("玩家id" + userId + "离开游戏大厅");
        } else {
            log.info("[afterConnectionClosed]当前用户尚未登录");
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);
        if (!ObjectUtils.isEmpty(userId)) {

            WebSocketSession tmpSession = onlineUserManager.getGameHallSession(userId);
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(userId);
                onlineUserManager.exitGameRoom(userId);
            }
            gameMatch.remove(userId);
            log.info("玩家id" + userId + "离开游戏大厅");
        } else {
            log.info("[afterConnectionClosed]当前用户尚未登录");
        }

    }

}
